﻿#include "WRWorkTcpCommClientSession.h"
#include "WRWorkTcpCommClientRoutine.h"
#include "WRWorkTcpCommClientObject.h"

#include <QTextCodec>

namespace WRUtils
{
    //设置工作TCP通讯客户对象映射。
    static void setMapping(WRWorkTcpCommClientObject* object, WRArray<WRWorkTcpCommClientObject*>& objects)
    {
        objects[object->index()] = object;

        auto& children = object->children();
        for(WRu i = 0, l = children.count(); i < l; ++i)
        {
            setMapping((WRWorkTcpCommClientObject*)(children[i]), objects);
        }
    }
}

//初始化工作TCP通讯客户端会话
WRWorkTcpCommClientSession::WRWorkTcpCommClientSession(WRWorkTcpCommClientRoutine* owner, int count, const char* buffer)
    : WRWorkSession(owner->owner()), m_owner(owner), m_objects(count)
{
    const QUuid* uuid = (const QUuid*)buffer;//类型标识+唯一标识
    const WR16u* sIdxCnt = (const WR16u*)(uuid + count * 2);//父对象索引+子对象数量
    const WR16u* sLen = (const WR16u*)(sIdxCnt + count * 2);//名称长度+描述长度
    const char* sTxt = (const char*)(sLen + count * 2);
    QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    for(int i = 0; i < count; ++i)
    {
        WR16u nLen0 = WRBytes::read<WR16u>(&sLen[0]);
        WR16u nLen1 = WRBytes::read<WR16u>(&sLen[1]);
        WR16u nIdx = WRBytes::read<WR16u>(&sIdxCnt[0]);
        WR16u nCnt = WRBytes::read<WR16u>(&sIdxCnt[1]);
        if (nIdx != 0xFFFF)
        {
            m_objects[i] = new WRWorkTcpCommClientObject(
                        WRWorkInformation(WRBytes::read<QUuid>(&uuid[1]),
                            codec->toUnicode(sTxt, nLen0),
                            codec->toUnicode(sTxt + nLen0, nLen1)),
                        WRType::select(WRBytes::read<QUuid>(&uuid[0])),
                        m_objects[nIdx],
                        i,
                        nCnt);
        }
        else
        {
            m_objects[i] = new WRWorkTcpCommClientObject(
                        WRWorkInformation(WRBytes::read<QUuid>(&uuid[1]),
                            codec->toUnicode(sTxt, nLen0),
                            codec->toUnicode(sTxt + nLen0, nLen1)),
                        WRType::select(WRBytes::read<QUuid>(&uuid[0])),
                        this,
                        i,
                        nCnt);
            m_children.append(m_objects[i]);
        }
        uuid += 2;
        sLen += 2;
        sIdxCnt += 2;
        sTxt += nLen0 + nLen1;
    }

    setObjects(m_children);
    for(WRu i = 0, l = m_children.count(); i < l; ++i)
    {
        auto child = (WRWorkTcpCommClientObject*)(m_children[(int)i]);
        child->init();
    }
}
//初始化工作TCP通讯客户端会话
WRWorkTcpCommClientSession::WRWorkTcpCommClientSession(WRWorkTcpCommClientRoutine* owner, WRWorkTcpCommClientSession* before)
    : WRWorkSession(owner->owner()), m_owner(owner), m_objects(before->m_objects.count())
{
    for(WRu i = 0, l = before->m_children.count(); i < l; ++i)
    {
        m_children[(int)i] = static_cast<WRWorkTcpCommClientObject*>(before->m_children[(int)i])->clone(this);
    }

    setObjects(m_children);
    for(WRu i = 0, l = m_children.count(); i < l; ++i)
    {
        auto child = (WRWorkTcpCommClientObject*)(m_children[(int)i]);
        child->init();
        WRUtils::setMapping(child, m_objects);
    }
}
//清理当前对象所占用的相关资源。
WRWorkTcpCommClientSession::~WRWorkTcpCommClientSession(void)
{
    //add code here
}

//处理接收到数据。
void WRWorkTcpCommClientSession::procData(WR32u idx, const unsigned char* buf, int len)
{
    if (idx < m_objects.count())
    {
        static_cast<WRWorkTcpCommClientObject*>(m_objects[idx])->procData(buf, len);
    }
}
//发送数据。
bool WRWorkTcpCommClientSession::sendData(WRDataPacket* packet)
{
    QMutexLocker lck(&m_mutex);
    if (m_owner)
    {
        return m_owner->process(packet);
    }
    return false;
}
